package parsing;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class XMLToDeckJS {
	private static String style;
	private static String animation;
	
	private static boolean commandLineOutput = false;

	
	private static PrintWriter outputStream;
	private static File htmlFile;

	public static void main(String argv[]) {
		File f = new File("slidespresso/testxml/file.xml");
		handleXml(f);
	}

	public static void handleXml(File file) {

		try {
			if (!commandLineOutput) {
				setupHTMLWriter();
			}

			Document doc = getXMLDocument(file);
			style = doc.getDocumentElement().getAttribute("theme");
			animation = doc.getDocumentElement().getAttribute("animation");
			
					
			writeHeader(doc);
			writeString(DeckJSStrings.BODY_PRE);

			NodeList nodes = doc.getElementsByTagName("slide");
			handleSlides(nodes);
			
			writeString(DeckJSStrings.BODY_POST);
			
			closeHTMLWriter();
			
			ZipWriter.writeZip("zipfile.zip", htmlFile, style, animation);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private static Document getXMLDocument(File file) {
		DocumentBuilderFactory domFactory = DocumentBuilderFactory
				.newInstance();
		domFactory.setNamespaceAware(true);

		Document doc = null;
		try {
			DocumentBuilder builder = domFactory.newDocumentBuilder();
			doc = builder.parse(file);
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return doc;

	}

	public static void setupHTMLWriter() throws IOException {

		htmlFile = new File("index.html");
		outputStream = new PrintWriter(htmlFile);

	}

	public static void closeHTMLWriter() throws IOException {
		if (outputStream != null) {
			outputStream.close();
			System.out.println("writer closed");
		}
	}

	public static void handleSlides(NodeList nodes) {
		for (int i = 0; i < nodes.getLength(); i++) {
			writeStringln(String.format("<section class=\"slide\" %s>", nodes
					.item(i).getAttributes().getNamedItem("id").toString()));

			handleContentNodes(nodes.item(i).getChildNodes());

			writeStringln("</section>");
		}
	}

	private static void handleContentNodes(NodeList content) {
		// writeString("Content call ");
		for (int i = 0; i < content.getLength(); i++) {
			handleNode(content.item(i));
		}
	}

	private static void handleNode(Node node) {
		String nodeName = node.getNodeName();
		if (node.getNodeType() == Node.ELEMENT_NODE) {

			if (nodeName == "h1") {
				writeContentH1(node);
			} else if (nodeName == "h2") {
				writeContentH2(node);
			} else if (nodeName == "h3") {
				writeContentH3(node);
			} else if (nodeName == "img") {
				writeContentImg(node);
			} else if (nodeName == "ol") {
				writeContentOl(node);
			} else if (nodeName == "ul") {
				writeContentUl(node);
			} else if (nodeName == "text") {
				writeStringln("<p>" + node.getTextContent() + "</p>");
			} else {
				writeStringln(node.getTextContent());
				writeStringln("NOT SUPPORTED:" + nodeName + node.getNodeValue());
			}
		}

	}

	private static void handleListNodes(NodeList content) {
		// writeString("List call ");
		for (int i = 0; i < content.getLength(); i++) {
			if (content.item(i).getNodeName() == "li") {
				writeStringln("<li>");
				handleContentNodes(content.item(i).getChildNodes());
				writeStringln("</li>");
			}
		}
	}

	private static void writeContentOl(Node node) {
		writeStringln("<ol>");
		handleListNodes(node.getChildNodes());
		writeStringln("</ol>");
	}

	private static void writeContentUl(Node node) {
		writeStringln("<ul>");
		handleListNodes(node.getChildNodes());
		writeStringln("</ul>");
	}

	private static void writeContentImg(Node node) {
		writeStringln("image");
	}

	public static void writeContentH1(Node node) {
		writeString("<h1>");
		writeString(node.getTextContent());
		writeStringln("</h1>");
	}

	public static void writeContentH2(Node node) {
		writeString("<h2>");
		writeString(node.getTextContent());
		writeStringln("</h2>");
	}

	public static void writeContentH3(Node node) {
		writeString("<h3>");
		writeString(node.getTextContent());
		writeStringln("</h3>");
	}

	public static void writeHeader(Document doc) {
		writeStringln(DeckJSStrings.HEADER_PRE);
		writeStringln("<title>" + doc.getDocumentElement().getAttribute("title") + "</title>");
		
		if (!style.equals("")) {
			writeStringln("<!-- Theme -->\n<link rel=\"stylesheet\" href=\"deckjs/themes/style.css\" type=\"text/css\">\n");
		}
		
		if (!animation.equals("")) {
			writeStringln("<!-- Transition Theme -->\n<link rel=\"stylesheet\" href=\"deckjs/themes/transition.css\" type=\"text/css\">");
		}
		writeStringln(DeckJSStrings.HEADER_POST);
		
	}

	public static void writeFooter() {
	}
	
	public static void writeString(String s) {
		if (commandLineOutput) {
			System.out.print(s);
		} else {
			outputStream.print(s);
		}
	}

	public static void writeStringln(String s) {
		if (commandLineOutput) {
			System.out.println(s);
		} else {
			outputStream.println(s);
		}
	}
}
